import java.util.Scanner;

public class Test {


    //对称之美(字符串+哈希)
    //链接：https://ac.nowcoder.com/acm/problem/214850
    //来源：牛客网
    //给出n个字符串，从第1个字符串一直到第n个字符串每个串取一个字母来构成一个新字符串，
    // 新字符串的第i个字母只能从第i行的字符串中选出，这样就得到了一个新的长度为n的字符串，请问这个字符串是否有可能为回文字符串？
    //输入描述:
    //第一行一个数字t,1≤t≤50,代表测试数据的组数
    //每组测试数据先给出一个数字 n，然后接下来n行每行一个只由小写字母组成的字符串si
    //1≤n≤100,1≤si≤50
    //输出描述:
    //在一行中输出 “Yes” or “No”
    //示例1
    //输入
    //2
    //1
    //a
    //3
    //a
    //b
    //c
    //输出
    //Yes
    //No
    public static boolean check(boolean[][] hash,int l,int r){
        for (int i = 0; i < 26; i++) {
            if (hash[l][i] && hash[r][i]) return true;
        }
        return false;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int t= in.nextInt();
        while(t-- != 0){
            int n = in.nextInt();
            boolean[][] hash = new boolean[n][26];
            for (int i = 0; i < n; i++) {
                char[] s = in.next().toCharArray();
                for (char ch: s ) {
                    hash[i][ch-'a'] = true;
                }
            }
            int l = 0;
            int r = n-1;
            while(l<r){
                if (!check(hash,l,r)) break;
                l++;
                r--;
            }
            if (l<r) System.out.println("No");
            else System.out.println("Yes");
        }
    }


    //礼物的最大价值(动态规划-路径问题)
    //在一个m×n的棋盘的每一格都放有一个礼物，每个礼物都有一定的价值（价值大于 0）。
    // 你可以从棋盘的左上角开始拿格子里的礼物，并每次向右或者向下移动一格、直到到达棋盘的右下角。
    // 给定一个棋盘及其上面的礼物的价值，请计算你最多能拿到多少价值的礼物？
    //如输入这样的一个二维数组，
    //[
    //[1,3,1],
    //[1,5,1],
    //[4,2,1]
    //]
    //那么路径 1→3→5→2→1 可以拿到最多价值的礼物，价值为12
    //示例1
    //输入：
    //[[1,3,1],[1,5,1],[4,2,1]]
    //返回值：
    //12
    public int[][] dp = new int[210][210];
    public int maxValue(int[][] grid){
        int m = grid.length;
        int n = grid[0].length;
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                dp[i][j] += Math.max(dp[i-1][j],dp[i][j-1])+grid[i-1][j-1];
            }
        }
        return dp[m][n];
    }



    //小易的升级之路(数学+模拟)
    //小易经常沉迷于网络游戏.有一次,他在玩一个打怪升级的游戏,他的角色的初始能力值为 a.在接下来的一段时间内,
    // 他将会依次遇见n个怪物,每个怪物的防御力为b1,b2,b3...bn. 如果遇到的怪物防御力bi小于等于小易的当前能力值c,
    // 那么他就能轻松打败怪物,并 且使得自己的能力值增加bi;如果bi大于c,那他也能打败怪物,但他的能力值只能增加bi 与c的最大公约数.
    // 那么问题来了,在一系列的锻炼后,小易的最终能力值为多少?
    //输入描述：
    //对于每组数据,第一行是两个整数n(1≤n<100000)表示怪物的数量和a表示小易的初始能力值.
    // 然后输入n行，每行整数,b1,b2...bn(1≤bi≤n)表示每个怪物的防御力
    //输出描述：
    //对于每组数据,输出一行.每行仅包含一个整数,表示小易的最终能力值
    //示例1
    //输入：
    //3 50
    //50 105 200
    //5 20
    //30 20 15 40 100
    //输出：
    //110
    //205
    public static int gcd(int x,int b){
        if (b==0) return x;
        return gcd(b, x%b);
    }
    public static void main1(String[] args) {
        Scanner in  = new Scanner(System.in);
        while (!in.hasNext()) {
            int n = in.nextInt();
            int x = in.nextInt();
            int b = 0;
            for (int i = 0; i < n; i++) {
                b = in.nextInt();
                if (b <= x) {
                    x += b;
                } else {
                    x += gcd(x, b);
                }
            }
            System.out.println(x);
        }
    }
}



